//-----------------------------------------------------------------------
// <copyright file="ResultReader.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Ben Lilley</author>
// <email>benjililley@hotmail.com</email>
// <date>2007-07-23</date>
// <summary>Utility for reading Sourcegear Vault command line client XML output.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Vault
{
    using System;
    using System.Xml;

    /// <summary>
    /// <para>Utillity class for reading xml formatted resposnes from the Vault command line client.  May be extended in the future to handle operations that return datasets (such as history, diff, etc).</para>
    /// </summary>
    class ResultReader
    {
        /// <summary>
        /// Parses an xml string into a Result object that represents the error status and message from the Vault command line client.
        /// </summary>
        /// <param name="xml">Xml string returned from Vault command line client.</param>
        /// <returns>Result object.</returns>
        public static Result ReadResult(string xml)
        {
            Result result = new Result();
            result.Success = false;

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);

            /*************************************************
             *   Determine success / failure
             * ***********************************************/

            // ver 4.0
            XmlNode resultNode = xmlDoc.SelectSingleNode("vault/result/success");
            if (resultNode != null)
            {
                result.Success = Convert.ToBoolean(resultNode.InnerText);
            }
            else
            {
                // ver 3.0
                resultNode = xmlDoc.SelectSingleNode("vault/result");
                if (resultNode != null)
                {
                    XmlAttribute success = resultNode.Attributes["success"];
                    if (success != null)
                    {
                        result.Success = (success.Value == "yes" ? true : false);
                    }
                }
            }

            /*************************************************
             *   If failure, get exception or error text
             * ***********************************************/
            if (!result.Success)
            {
                // ver 4.0 only has exception
                XmlNode exception = xmlDoc.SelectSingleNode("vault/error/exception");
                if (exception != null)
                {
                    result.Exception = exception.InnerText;
                }
                else
                {
                    // ver 3.0

                    // provide exception if available (more descriptive)
                    exception = xmlDoc.SelectSingleNode("vault/exception");
                    if (exception != null)
                    {
                        result.Exception = exception.InnerText;
                    }
                    else
                    {
                        // provide error if no exception
                        exception = xmlDoc.SelectSingleNode("vault/error");
                        if (exception != null)
                        {
                            result.Exception = exception.InnerText;
                        }
                    }
                }
            }

            return result;
        }
    }

    /// <summary>
    /// Utility class to store return values from Vault command line client.
    /// </summary>
    public class Result
    {
        private bool success;
        private string exception;

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Result"/> is success.
        /// </summary>
        /// <value><c>true</c> if success; otherwise, <c>false</c>.</value>
        public bool Success
        {
            get { return this.success; }
            set { this.success = value; }
        }

        /// <summary>
        /// Gets or sets the exception.
        /// </summary>
        /// <value>The exception.</value>
        public string Exception
        {
            get { return (this.exception ?? String.Empty); }
            set { this.exception = value; }
        }
    }
}

